package com.zeng.sim.listener;

import com.zeng.sim.support.server.socket.ServerSimSocket;
import com.zeng.sim.util.SimConstant;
import com.zeng.sim.util.SysConfigUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 描述信息
 *
 * @author zengwanlin
 * @date 2023-12-25T13:26
 */
@Component
public class MsgSimulatorStartupListener implements ApplicationListener<ContextRefreshedEvent> {

    private Logger logger = LoggerFactory.getLogger(MsgSimulatorStartupListener.class);

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        try {

            // 初始化模拟服务端-Socket服务
            initServerSim(event.getApplicationContext());

        }
        catch (Exception e) {
            if (e instanceof BeansException) {
                throw e;
            }
            throw new BeanCreationException(e.getMessage(), e);
        }
    }

    /**
     * 初始化模拟服务端-Socket服务
     */
    private void initServerSim(ApplicationContext context) {
        logger.info("模拟服务端-Socket服务-初始化 begin");
        if (!SimConstant.VALID_FLAG_1
            .equals(SysConfigUtil.getSystemConfigValue(SysConfigUtil.CONFIG_CODE_SERVER_SIM_SOCKET_ENABLE))) {
            logger.info("模拟服务端-Socket服务-未启用");
            return;
        }
        Integer listenPort = Integer
            .parseInt(SysConfigUtil.getSystemConfigValue(SysConfigUtil.CONFIG_CODE_SERVER_SIM_SOCKET_LISTEN_PORT));
        if (!portAvailable(listenPort)) {
            throw new IllegalArgumentException("端口[" + listenPort + "]已被占用，请修改配置[模拟服务端-Socket服务监听端口]");
        }

        ServerSimSocket serverSimSocket = new ServerSimSocket(listenPort,
                context.getBean("busiPoolExecutor", ThreadPoolExecutor.class));
        Thread thread = new Thread(serverSimSocket);
        thread.setDaemon(true);
        thread.start();

        logger.info("模拟服务端-Socket服务-初始化 end");
    }

    /**
     * 判断端口是否可用
     * @param port
     * @return true-可用，false-不可用
     */
    private boolean portAvailable(Integer port) {
        Socket socket = null;
        try {
            socket = new Socket();
            socket.connect(new InetSocketAddress(port), (int) TimeUnit.SECONDS.toMillis(10));
            socket.close();
        }
        catch (IOException e) {
            return true;
        }
        finally {
            if (socket != null) {
                try {
                    socket.close();
                }
                catch (IOException e) {
                    logger.error("关闭Socket出错，" + e.getMessage(), e);
                }
            }
        }
        return false;
    }

}
